<template>
  <div>
    <div ref="mapContainer" style="height: calc(100vh - 50px)"></div>

    <div class="absolute right-10px z-10 top-55px">
      <el-tooltip effect="light" placement="left" :enterable="false" content="组织结构">
        <div class="map-tool-button" :class="{ 'button-active': treeVisible }" @click="treeVisible = !treeVisible">
          <svg-icon icon-class="station-list" />
        </div>
      </el-tooltip>
      <el-tooltip effect="light" placement="left" :enterable="false" content="测点状态">
        <div class="map-tool-button" :class="{ 'button-active': stateVisible }" @click="stateVisible = !stateVisible">
          <svg-icon icon-class="quick-menu" />
        </div>
      </el-tooltip>
      <el-tooltip effect="light" placement="left" :enterable="false" content="实时数据">
        <div class="map-tool-button" :class="{ 'button-active': realtimeDataRef?.visible }" @click="showRealtimeData">
          <svg-icon icon-class="current-data" />
        </div>
      </el-tooltip>
      <el-tooltip effect="light" placement="left" :enterable="false" content="实时报警">
        <div class="map-tool-button" :class="{ 'button-active': realtimeAlarmRef?.visible }" @click="realtimeAlarmRef?.show()">
          <svg-icon icon-class="alert" />
        </div>
      </el-tooltip>
    </div>

    <!-- 搜索框 -->
    <div class="absolute right-10px top-10px z-10 w-220px">
      <el-autocomplete
        value-key="label"
        v-model="mapSearchText"
        :fetch-suggestions="querySearchMethod"
        placeholder="请输入要搜索的内容"
        @select="mapMethods.flyTo($event.position, $event.zoom)"
      />
    </div>

    <!-- 测点树 -->
    <transition name="el-fade-in-linear">
      <div class="absolute top-55px right-60px z-10" v-show="treeVisible">
        <el-card header="组织结构" class="w-240px">
          <el-input class="mb-10px" placeholder="请输入关键字查询" v-model="treeSearchText" @input="handleSearchTree" />
          <el-tree
            ref="stationTreeRef"
            class="h-400px overflow-auto"
            show-checkbox
            :expand-on-click-node="false"
            :data="stationTree"
            node-key="id"
            :filter-node-method="searchTreeMethod"
            @node-click="handleMapFlyTo"
            @check="filterTreeMap"
          />
        </el-card>
      </div>
    </transition>

    <!-- 测点状态 -->
    <transition name="el-fade-in-linear">
      <div class="absolute top-105px right-60px z-10" v-show="stateVisible">
        <el-card>
          <el-table
            ref="stateTableRef"
            :header-cell-style="{ 'background-color': '#fff!important' }"
            :border="false"
            :data="stationStateList"
            @selection-change="filterStateMap"
          >
            <el-table-column label="测点状态" width="150">
              <template #default="{ row }">
                <div class="flex items-center">
                  <div class="w-10px h-10px border-rd-5px mr-10px" :style="{ backgroundColor: computeAlarmColor(row.alarmLevel) }" />
                  <span>{{ `${computeAlarmTitle(row.alarmLevel)}（${row.count}）` }}</span>
                </div>
              </template>
            </el-table-column>
            <el-table-column type="selection" />
          </el-table>
        </el-card>
      </div>
    </transition>

    <!-- 实时数据 -->
    <RealtimeData ref="realtimeDataRef" />
    <!-- 实时报警 -->
    <RealtimeAlarm ref="realtimeAlarmRef" />

    <!-- 测点详情 -->
    <station-details-dialog v-model="stationDetail.visible" :stcd="stationDetail.stcd" />
    <!-- 测站详情 -->
    <SiteDetail ref="siteDetailRef" />
  </div>
</template>

<script setup lang="ts">
import { computeAlarmColor, computeAlarmTitle, convertStringToLatLng, convertStringToPath } from '@/utils/gis';
import SiteDetail from '../gis/components/SiteDetail.vue';
import RealtimeData from '@/views/dataCenter/gis/components/RealtimeData.vue';
import RealtimeAlarm from '@/views/dataCenter/gis/components/RealtimeAlarm.vue';
import { listOverlay } from '@/api/dataCenter/gisEditor';
import { GisEditorVO } from '@/api/dataCenter/gisEditor/types';
import getScriptAsync from './utils/getScriptAsync';
import { initPolyline, initPolygon, initStationMarker, initSiteMarker } from './utils/bigemap';
import { listStationTreeInfo } from '@/api/dataCenter/gis';
import { StationTreeVO } from '@/api/dataCenter/common/types';
import { listStationAlarm } from '@/api/communicateSettings/station';
import { listSiteNoPageByAuth } from '@/api/communicateSettings/sites';
import { SitesVO } from '@/api/communicateSettings/sites/types';
import { StationVO } from '@/api/communicateSettings/station/types';
import boundaryData from './utils/boundary.json';
import useAppStore from '@/store/modules/app';
import {isProd,mapCenterAsCenter} from '@/consts.ts';

const appStore = useAppStore();
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
const mapContainer = ref<HTMLElement | null>();
let map: any = null; // 地图实例
let BM: any = null;
let stationLayers: any = null;
let siteLayers: any = null;
let mapMethods: any = null;
const stationTreeRef = ref<ElTreeInstance>();
const stateTableRef = ref<ElTableInstance>();
const realtimeDataRef = ref<InstanceType<typeof RealtimeData>>();
const realtimeAlarmRef = ref<InstanceType<typeof RealtimeAlarm>>();
const siteDetailRef = ref<InstanceType<typeof SiteDetail>>();

let mapCenter = { lng: 118.184217, lat: 39.64003 }; // 地图中心
let overlayList: GisEditorVO[] = []; // 绘制线列表
const mapSearchText = ref(''); // 地图搜索关键词
const treeVisible = ref(false); // 测点树显示
const treeSearchText = ref(''); // 树搜索关键词
const stationTree = ref<StationTreeVO[]>([]); // 测点树
let filteredTreeList: string[] = []; // 测点树过滤条件
let filteredStateList: string[] = []; // 测点状态过滤条件
const stateVisible = ref(false); // 测点状态显示
let siteListAll: SitesVO[] = []; // 所有测站列表
// let siteIds: string[] = []; // 地图展示测站列表
let stationListAll: StationVO[] = []; // 所有测点列表
let stationIds: string[] = []; // 地图展示测点列表

// 测点详情
const stationDetail = ref({
  visible: false,
  stcd: ''
});

// 获取测点树
const getStationTree = async () => {
  const { data } = await listStationTreeInfo();
  // console.log(data);
  stationTree.value = data;
};

// 树搜索文本框
const handleSearchTree = () => {
  stationTreeRef.value?.filter(treeSearchText.value);
};

// 树搜索文本框所用方法
const searchTreeMethod = (value: string, data: any) => {
  if (!value) return true;
  return data.label.toLowerCase().includes(value.toLowerCase());
};

// 筛选测点树控制测点在地图上显示
const filterTreeMap = (
  e1: any,
  treeCheckedData: { checkedNodes: any[]; checkedKeys: string[]; halfCheckedNodes: any[]; halfCheckedKeys: string[] }
) => {
  filteredTreeList = treeCheckedData.checkedKeys;
  // TODO
  filterStationMap();
  filterSiteMap();
};

// 筛选报警状态控制测点在地图上显示
const filterStateMap = (selection: any[]) => {
  // console.log(selection);
  filteredStateList = selection.map((item) => item.alarmLevel);
  // TODO
  filterStationMap();
  filterSiteMap();
};

// 综合筛选控制测点在地图上显示
const filterStationMap = () => {
  stationIds = [];
  // console.log(stationLayers);
  stationLayers.eachLayer((layer: any) => {
    if (filteredStateList.includes(layer.stationProps.alarmLevel) && filteredTreeList.includes(layer.stationProps.stcd)) {
      stationIds.push(layer.stationProps.stcd);
      setStationVisible(layer, true);
    } else {
      setStationVisible(layer, false);
    }
  });
};

// 综合筛选控制测站在地图上显示
const filterSiteMap = () => {
  // siteIds = [];
  // console.log(siteLayers);
  siteLayers.eachLayer((layer: any) => {
    if (filteredStateList.includes(layer.stationProps.alarmLevel) && filteredTreeList.includes(layer.stationProps.sitesId)) {
      // siteIds.push(layer.stationProps.sitesId);
      setStationVisible(layer, true);
    } else {
      setStationVisible(layer, false);
    }
  });
};

// 测点测站显示隐藏
const setStationVisible = (layer: any, visible: boolean) => {
  layer._icon.style.display = visible ? 'block' : 'none';
  // const originalOpacity = layer.options.opacity;
  // if (visible) {
  //   if (originalOpacity === 1) return;
  //   layer.setOpacity(1);
  //   // 测点
  //   if (layer.stationProps.stcd) {
  //     layer.on('click', () => {
  //       stationDetail.value = {
  //         visible: true,
  //         stcd: layer.stationProps.stcd
  //       };
  //     });
  //   } else if (layer.stationProps.sitesId) {
  //     // 测站
  //     layer.on('click', () => {
  //       siteDetailRef.value?.show(layer.stationProps.sitesId);
  //     });
  //   }
  // } else {
  //   if (originalOpacity === 0) return;
  //   layer.setOpacity(0);
  //   layer.off('click');
  // }
};

// 测点状态列表
const stationStateList = ref([
  { alarmLevel: '', count: 0 },
  { alarmLevel: '0', count: 0 },
  { alarmLevel: '1', count: 0 },
  { alarmLevel: '2', count: 0 },
  { alarmLevel: '3', count: 0 }
]);

// 地图级别变化测点测站显隐
const handleStationVisibleZooming = (mapZoom: number) => {
  stationLayers.eachLayer((layer: any) => {
    if (layer.stationProps.zoom <= mapZoom) {
      setStationVisible(layer, true);
    } else {
      setStationVisible(layer, false);
    }
  });

  siteLayers.eachLayer((layer: any) => {
    if (layer.stationProps.zoom <= mapZoom) {
      setStationVisible(layer, true);
    } else {
      setStationVisible(layer, false);
    }
  });
};

// 获取测点列表
const getStationList = async () => {
  const { data } = await listStationAlarm();
  stationListAll = data;
  stationListAll.forEach((item) => {
    const marker = initStationMarker(stationLayers, item);
    marker.on('click', () => {
      stationDetail.value = {
        visible: true,
        stcd: item.stcd
      };
    });
  });
  // 统计各状态测点数量
  countState(stationListAll);
};

// 初始化测点状态 测点树均为全选状态
const initChecked = async () => {
  await getSiteList();
  await getStationList();
  await getStationTree();
  stateTableRef.value?.toggleAllSelection(); // 状态全选=>会触发table的selection-change事件
  stationTreeRef.value?.setCheckedNodes(stationTree.value as any); // 树全选=>不会触发tree的check事件
  filteredTreeList = stationTreeRef.value?.getCheckedKeys() as string[];
};

// 展示实时数据
const showRealtimeData = () => {
  realtimeDataRef.value?.show(stationIds.join(','));
};

// 统计状态
const countState = (arr: any[]) => {
  arr.forEach((item) => {
    switch (item.alarmLevel) {
      case '':
        stationStateList.value[0].count++;
        break;
      case '0':
        stationStateList.value[1].count++;
        break;
      case '1':
        stationStateList.value[2].count++;
        break;
      case '2':
        stationStateList.value[3].count++;
        break;
      case '3':
        stationStateList.value[4].count++;
        break;
    }
  });
};

// 左上搜索框搜索方法
const querySearchMethod = (queryString: string, cb: any) => {
  if (!queryString) {
    cb([]);
  } else {
    // 搜索覆盖物列表
    const OverlayRes = overlayList
      .filter((item) => item.label.toLowerCase().includes(queryString.toLowerCase()))
      .map((item) => ({ label: item.label, position: convertStringToLatLng(item.center) }));
    // 搜索测点列表
    const stationRes = stationListAll
      .filter((item) => item.stnm.toLowerCase().includes(queryString.toLowerCase()))
      .map((item) => ({ label: item.stnm, position: convertStringToLatLng(item.stlalo), zoom: item.mapLevel }));
    // 搜索测站列表
    const siteRes = siteListAll
      .filter((item) => item.sitesName.toLowerCase().includes(queryString.toLowerCase()))
      .map((item) => ({ label: item.sitesName, position: convertStringToLatLng(item.mapPoints), zoom: item.mapLevel }));
    cb(OverlayRes.concat(stationRes).concat(siteRes));
  }
};

// 获取测站列表
const getSiteList = async () => {
  const { data } = await listSiteNoPageByAuth({ mapShowType: '0' });
  siteListAll = data;
  siteListAll.forEach((item) => {
    const marker = initSiteMarker(siteLayers, item);
    marker.on('click', () => {
      siteDetailRef.value?.show(item.sitesId);
    });
  });
  // console.log(siteLayers);
};

// 获取绘制线/区域列表
const getOverlayList = async () => {
  const { rows } = await listOverlay();
  rows.forEach((item) => {
    item.path = convertStringToPath(item.path);
  });
  overlayList = rows;
  // 线
  const polylineList = rows.filter((item) => item.type === '1');
  polylineList.forEach((item) => {
    initPolyline(map, item);
  });
  // 区域
  const polygonList = rows.filter((item) => item.type === '2');
  polygonList.forEach((item) => {
    initPolygon(map, item);
  });
};

// 地图跳转
const handleMapFlyTo = (node: any) => {
  if (node.weight === 1) {
    mapMethods.flyTo(convertStringToLatLng(node.info.mapPoints), 13);
  } else if (node.weight === 3) {
    mapMethods.flyTo(convertStringToLatLng(node.info.stlalo), 13);
  }
};

// 获取地图中心点
const getMapCenter = async () => {
  // const centerRes: any = await proxy?.getConfigKey('gis.map.center');
  const centerRes: any = {
    data: mapCenterAsCenter.value,
  };
  if (centerRes.data) {
    mapCenter = convertStringToLatLng(centerRes.data);
  }
};

//
// const handleBoundsZooming = (zoom: number) => {
//   if (zoom > 11) {
//     map.setMaxBounds([
//       { lng: 128.009, lat: 46.2122 },
//       { lng: 129.766, lat: 45.4515 }
//     ]);
//   } else {
//     map.setMaxBounds([
//       { lng: 124.05212402343751, lat: 47.34812813983327 },
//       { lng: 130.91033935546878, lat: 44.822760189927365 }
//     ]);
//   }
// };

// 地图初始化
const initMap = () => {
  if (!mapContainer.value) return;
  getScriptAsync({ exportGetter: () => window.BM }).then(() => {
    BM = window.BM;
    BM.Config.HTTP_URL = import.meta.env.VITE_APP_BM_Config_HTTP_URL;

    map = BM.map(mapContainer.value, null, {
      center: mapCenter,
      zoom: 11,
      minZoom: 9,
      maxZoom: 21,
      zoomControl: false
    });

    map.setMaxBounds([
      { lng: 128.009, lat: 46.2122 },
      { lng: 129.766, lat: 45.4515 }
    ]);

    let layerHeiLongJiang = null;
    let layerFangZheng = null;
    if (!isProd) {
      /**
       * 测试服务器配置
       */
      BM.tileLayer('bigemap.7uwzym4u').addTo(map); // 中国
      layerHeiLongJiang = BM.tileLayer('bigemap.2pkf0tpb').addTo(map); // 黑龙江
      layerFangZheng = BM.tileLayer('bigemap.8o7zo2n0').addTo(map); // 方正
    }

    if (isProd) {
      /**
       * 客户服务器配置
       */
      BM.tileLayer('bigemap.bh600n8z').addTo(map); // 中国
      layerHeiLongJiang = BM.tileLayer('bigemap.5p46muyu').addTo(map); // 黑龙江
      layerFangZheng = BM.tileLayer('bigemap.cucjpko5').addTo(map); // 方正
    }

    setTimeout(() => {
      Object.assign(layerFangZheng.options, {
        maxNativeZoom: 15,
        maxZoom: 21
      });
      Object.assign(layerHeiLongJiang.options, {
        maxNativeZoom: 11,
        maxZoom: 18
      });
    }, 500);

    BM.polyline(convertStringToPath(boundaryData.boundary), { color: 'blue', weight: 2 }).addTo(map); // 边界

    map.on('zoomend', () => {
      const zoom = map.getZoom();
      handleStationVisibleZooming(zoom);
      // handleBoundsZooming(zoom);
    });

    // map.on('click', (e: any) => {
    //   console.log(e);
    // });

    stationLayers = BM.layerGroup([]).addTo(map);
    siteLayers = BM.layerGroup([]).addTo(map);
    initChecked();

    mapMethods = {
      flyTo: (position: { lng: number; lat: number }, zoom?: number) => {
        map.flyTo(position, !zoom || zoom < 13 ? 13 : zoom);
      }
    };
  });
};

onMounted(async () => {
  await getMapCenter();
  initMap();
  getStationTree();
  getOverlayList();

  appStore.openMain();
});
onBeforeUnmount(() => {
  appStore.closeMain();
});
</script>
